home *** CD-ROM | disk | FTP | other *** search
/ PC Media 22 / PC MEDIA CD22.iso / share / prog / datalib2 / database.txt < prev    next >
Text File  |  1995-08-16  |  84KB  |  2,336 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.                    C++ Database Library
  34.  
  35.  
  36.                  Version 2.3, 16th August 1995
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.        Package Contents
  44.        ================
  45.  
  46.        The package contains the following files:
  47.  
  48.        SOURCE.ZIP  The source files for the library.
  49.                This file contains the following files:
  50.  
  51.            DATABASE.CPP    Source file
  52.            DATAEXE1.CPP    Source file
  53.            DATAEXE2.CPP    Source file
  54.            FIELD.CPP       Source file
  55.            INDCLUS.CPP     Source file
  56.            INDEX.CPP       Source file
  57.            INDEX2.CPP      Source file
  58.            RECORD.CPP      Source file
  59.            UTIL.CPP        Source file
  60.            EXOP.HPP        Private header file
  61.            DATAPRIV.HPP    Private header file
  62.            DATABASE.HPP    Header file for all versions of the library
  63.  
  64.            DATABASE.TXT    User manual for library.
  65.            README.TXT      File list and conditions
  66.  
  67.            DBRPT.CPP       Example program
  68.  
  69.            FAMILYS.DBF     Example database
  70.            FAMILYS.CPP     Example program
  71.            FAMILYS.NDX     Index file for example database
  72.  
  73.            PACKDB.CPP      Example program
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81.  
  82.       Library, Conditions for use:
  83.       ============================
  84.  
  85.        This library of routines is provided as shareware. You may try the
  86.        functions defined in the library within in your own programs, however
  87.        if you decide to incorporate them permanently then you are obliged to
  88.        register your copy of the software. Registration costs ú30 UK sterling
  89.        or $40.00 (by cheque) to:
  90.  
  91.        Robin Abbott            Compuserve ID 100023,535
  92.        37 Plantation Drive,
  93.        Christchurch,
  94.        Dorset
  95.        ENGLAND
  96.  
  97.        BH23 5SG
  98.  
  99.        Compuserve Registration
  100.        =======================
  101.  
  102.        To register this library through Compuserve GO SWREG, and follow the
  103.        instructions there.
  104.        Use registration number 7118. Compuserve ID 100023,535
  105.  
  106.        Registration brings you the next library upgrade free of charge and
  107.        technical support.
  108.  
  109.        Compiled programs which incorporate the code within these libraries
  110.        may be distributed with no further royalty.
  111.  
  112.        The library may be freely distributed provided that all files are
  113.        included.
  114.  
  115.  
  116.     Known Bugs, 15/8/95
  117.     ===================
  118.  
  119.     I have now tested the index routines with 100,000 record databases,
  120.     generating and changing every single record in the database.
  121.     I am (fairly!) confident that all the significant bugs have been
  122.     ironed out, as these tests cover index tree depths of up to 6.
  123.     The verifyindex() routine has been made much more stringent and
  124.     shows valid index structures for all the tests I have carried out.
  125.  
  126.     Bug reports
  127.     ===========
  128.  
  129.     Send bug reports to the author. I will try to solve bugs and either
  130.     return an updated software version asap, or provide a work around.
  131.  
  132.     Simple bugs can just be reported, e.g. the bug that field names
  133.     could not have an underscore in them within the expression
  134.     evaluator.
  135.  
  136.     More complex bugs such as all the errors that occurred in the index
  137.     routines really need to identify the problem on a specific database.
  138.     This may not be easy, but please try and identify the routines which
  139.     cause the problem and send the complete database.
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146.       Introduction
  147.       ============
  148.  
  149.        This library is intended to allow Borland C++ programs to create,
  150.        write, interrogate and manipulate databases and indexes which are in
  151.        dBase III format. These files usually have the extension .dbf. The
  152.        library is based on a group of objects which represent databases,
  153.        records and fields.
  154.  
  155.        The library of functions will be of use in building database
  156.        applications and report generators, both standalone, and for use with
  157.        other database applications.
  158.  
  159.       Using the Library in Building Programs
  160.       ======================================
  161.  
  162.        The package incorporates 9 source files, which must be included in
  163.        the project build, or which can be built into a library. These files
  164.        are as follows:
  165.  
  166.            DATABASE.CPP    Source file (X)
  167.            DATAEXE1.CPP    Source file (X)
  168.            DATAEXE2.CPP    Source file (X)
  169.            FIELD.CPP       Source file (X)
  170.            INDCLUS.CPP     Source file (X)
  171.            INDEX.CPP       Source file (X)
  172.            INDEX2.CPP      Source file (X)
  173.            RECORD.CPP      Source file (X)
  174.            UTIL.CPP        Source file (X)
  175.  
  176.        These incorporate all the functions described in this
  177.        document and should be compiled using the large model. Copy
  178.        the header file database.hpp to your include directory.
  179.  
  180.        Programs which use the library must include the header file
  181.        database.hpp, and must be compiled using the large model.
  182.  
  183.       Using the Package
  184.       =================
  185.  
  186.        The package is intended to be as easy as possible to use. A database
  187.        object should be opened with the name of the database in which the
  188.        user is interested together with the first index file if required.
  189.        Additional index files may be added as required. A record object (or
  190.        many records) may now be opened on this database. The record object
  191.        may be positioned at any record in the file and the fields in the
  192.        record may be examined or modified. It is possible to select records
  193.        on a variety of criteria including dBase expressions.
  194.  
  195.        The following example shows a program which opens the file "CLUB.DBF"
  196.        and swaps the month and day for each record in the file. This was
  197.        written to correct an error in importing a file in American date
  198.        format. The file has a number of fields, the only one considered here
  199.        is the DOB field - the date of birth which was incorrectly imported.
  200.  
  201.        /*
  202.       Short Program to exchange Day & Month for every record in a
  203.            database
  204.        */
  205.  
  206.  
  207.  
  208.  
  209.  
  210.        #include <string.h>
  211.        #include <database.hpp>
  212.        #include <stdio.h>
  213.        #include <stdlib.h>
  214.  
  215.        void main()
  216.        {
  217.         char ws[128];              // Convenient Workspace
  218.  
  219.         database db("CLUB");       // Open database, no index
  220.  
  221.         record rec(db);            // Record open on database
  222.  
  223.     int fn=db.getfield("DOB")->getnumber();   // Get number of DOB field
  224.  
  225.     int sel=rec.select(FIRST);     // Select first record
  226.     while(!sel)                    // For every record in the file
  227.     {
  228.      int d,m,y;                    // day, month and year
  229.  
  230.      gnums(rec.getfield(fn),d,m,y);        // Get date of birth to d,m,y
  231.      sprintf(ws,"%04d%02d%02d",y,d,m);     // Print in db form, swap d&m
  232.      rec.setfield(fn,ws);                  // Update field
  233.      rec.write();                          // Write back to disk
  234.  
  235.          sel=rec.select(NEXT);                 // Select next record
  236.         }
  237.        }
  238.  
  239.       Indexes
  240.       =======
  241.  
  242.        The package is capable of handling dBase style NDX files (indexes).
  243.        These are attached using the database::addindex() function. Indexes
  244.        are referred to by the file name with no path and no extension. Thus
  245.        the index "c:\c\name.ndx" is referred to using the string "name".
  246.  
  247.        Indexes are usually attached when the database is opened, or when
  248.        they have been created. New records will be included in the index
  249.        only if the index is attached to the database. Should an out of date
  250.        index be attached to a database then there is a risk that the records
  251.        will be out of order, to check a database the database::verifyindex()
  252.        function may be used to check the index.
  253.  
  254.        Big Files
  255.        =========
  256.  
  257.        Large databases (greater than about 2000 records) need handling
  258.        carefully to avoid speed problems. Indexes should be built on these
  259.        databases as little as possible, being maintained by attaching them
  260.        to the database. Selecting records should be done by using the index
  261.        key (the record::selkey() function), which will be considerably
  262.        faster than using any of the record::select() functions - these
  263.        functions search the whole database from beginning to end. The
  264.        database::verifyindex() function should also be avoided as this
  265.        searches the entire database.
  266.  
  267.       Errors
  268.       ======
  269.  
  270.        The database will report fatal errors (by printing the errors on
  271.        screen) which may cause a crash such as opening a record on an
  272.        invalid database. Some more trivial errors which may be trapped by
  273.        the calling program will also be printed. The global variable eroff
  274.        should be set to 1 if it is required to turn off printing of these
  275.        non-fatal errors. Fatal errors are printed using printf for DOS
  276.        compilations, and using MessageBox() for Windows compilations.
  277.  
  278.  
  279.  
  280.  
  281.       Objects
  282.       =======
  283.  
  284.        There are three types of object used by application programs in the
  285.        database library.
  286.  
  287.        Database objects, Field Objects and Record Objects. A database object
  288.        holds the description of a database, field objects associated with the
  289.        database hold the definitions of the fields in the database, and
  290.        record objects hold all the information on a record.
  291.  
  292.       Assignment of Objects (Use of the = Operator)
  293.       =============================================
  294.  
  295.        The = operator may be used within the database library only to copy
  296.        one record to another (within the same database), this allows the
  297.        user to save the position and contents of a record within the
  298.        database, the = operator is implemented to ensure that a complete
  299.        copy of all structures and variables associated with the record is
  300.        made. An example of the use of this is shown above in the subtotals
  301.        program.
  302.  
  303.        The = operator must not be used with database objects or field
  304.        objects, or between records on different databases. See the example
  305.        program DBPACK below to see how a record may be copied between
  306.        different databases.
  307.  
  308.       DATABASE Objects
  309.       ================
  310.  
  311.        A database object is constructed with the name of the database to be
  312.        opened, and an optional index file. The file is opened and the user
  313.        then has the capability to determine the state of the file and the
  314.        fields in it. Constructing a database object automatically creates a
  315.        linked list of the fields in the database.
  316.  
  317.        To create a new database a database object is opened without a file
  318.        name, and then fields of any type can be added to the database. When
  319.        all the database fields have been written the database can be
  320.        established by saving it with a filename after which records may be
  321.        created within it.
  322.  
  323.        The database object has the following public interface:
  324.  
  325.        class database
  326.        {
  327.     public :
  328.  
  329.     char ers[81];       // Reports the error in an expression
  330.  
  331.     database(char *name,char *index=0);  // Construct with file+index
  332.     database(void);                      // Construct a new database
  333.     ~database(void);
  334.  
  335.     int   addfield(field *newfield);     // Copy field to new database
  336.     int   addfield(char *nm,int l=1,int rdp=0);   // Add field to new
  337.                               // database
  338.     int   addindex(char *fname);           // Add index to the database
  339.     int   buildindex(char *expr,char *fn,
  340.              void (*prog)(int,long)=0,
  341.              int ord=100);           // Build a newindex
  342.     field *getfield(int n)
  343.           {return(fielda[n-1]);}          // Return field n, 1<=n<=nfield
  344.     field *getfield(char *name);          // Get ptr to field by name
  345.     char  *getindkey(char *name);        // Get index key
  346.     int   getindtype(char *name);        // Get index type, OPINT,OPSTR
  347.     long  getnrec(void) {return(nrec);}        // Number of records
  348.     int   getreclen(void) {return(reclen);}    // Total record length
  349.     int   getnfield(void) {return(nfield);}    // Number of fields
  350.     int   getversion(int &maj,int &min);       // Get library version
  351.     int   isvalid(void) {return(valid);}        // Return valid flag
  352.     int   verifyindex(char *iname,int depth=1,
  353.               void (*progress)(int test,long recnum)=0,
  354.               int order=100);          // Verify an index
  355.     int   setdateformat(dates form);       // Set date format
  356.     int   subindex(char *iname);               // Subtract an index
  357.        }
  358.  
  359.       FIELD Objects
  360.       =============
  361.  
  362.        A field object is created to enable the functions associated with the
  363.        database to determine the format of the records. It also allows the
  364.        user to determine the type, name and parameters of any field. The
  365.        field type has the following public interface:
  366.  
  367.        class field
  368.        {
  369.     public:
  370.  
  371.     field(int number,char *name,char type,int length,int rdp,
  372.           int recpos);
  373.     ~field(void);
  374.                          // Accessor functions
  375.     int getnumber(void) {return(number);}    // Get no. of field in record
  376.     char *getname(void) {strcpy(namecop,name);
  377.                  return(namecop);}    // Get name of field
  378.     char gettype(void) {return(type);}       // Get type of field
  379.     int getlen(void) {return(len);}          // Get length of field
  380.     int getrdp(void) {return(rdp);}          // Get right of dp of field
  381.        };
  382.  
  383.       RECORD Objects
  384.       ==============
  385.  
  386.        There may be any number of record objects associated with each
  387.        database object. Each record object holds one record in the file, and
  388.        it is possible to load a record object with the first, last, next,
  389.        previous, or any numbered record in the database. The record object
  390.        has the following public interface:
  391.  
  392.        class record
  393.        {
  394.     public:
  395.  
  396.     record(class database &db,char *indname=0);
  397.     ~record(void);
  398.     void operator=(record &s);                 // Copy record entirely
  399.  
  400.     int eval(char *expr,void *result,int &rtype); // Evaluate expression
  401.     int eval(void *result,int &rtype);     // Evaluate prev. expression
  402.     int indchk(char *exp,int &rtype);      // check an index expression
  403.     char *indname();                       // Return index name
  404.     int seldbf(long n);                    // Select record in dbf
  405.     int select(long n,int type=NOTDEL,int df=0);  // Select rec number
  406.     int select(int field,int val,long n,
  407.                     int type=NOTDEL);     // Select fn==val
  408.     int select(int field,char *s,long n,
  409.                      int type=NOTDEL);    // Select field==s
  410.     int select(int field,void *s,
  411.                int (*comp)(void *,void *),
  412.                long n,int type=NOTDEL);   // User def select
  413.     int select(char *expr,long n,
  414.                     int type=NOTDEL); // Select when expr true
  415.     char *getfield(int n,int tf=1);        // Get field by number
  416.     char *getfield(char *name,int tf=1);   // Get field by name
  417.     long getrecnum() {return(rn);}         // Current record number
  418.     int  getdelstate() {return(delstate);} // Delete state of record
  419.     void setdelstate(int sval);            // Set delete state of record
  420.     int  selkey(char *value,int type=NOTDEL,
  421.                 int num=OPSTR);   // Select by key
  422.     int  selkey(double value,int type=NOTDEL);
  423.     int  selkey();                         // Find other records by key
  424.     int  setfield(char *name,char *value); // Set new value for field name
  425.     int  setfield(char *name,float value);
  426.     int  setfield(int number,char *value); // Set new value for field by #
  427.     int  setfield(int number,float value);
  428.     int  write(int type=OVER);             // Write rec to dbf
  429.        };
  430.  
  431.  
  432.       Representation of Field Types
  433.       =============================
  434.  
  435.        Field types in dBase are Numeric (N), Character (C), Date (D),
  436.        Logical (L) or Memo (M). They are held internally in the follwoing
  437.        forms:
  438.  
  439.       Numeric
  440.       -------
  441.  
  442.        Numeric fields are held in double (8 byte) form. When values are
  443.        returned from the database they are in ASCII form (e.g. 1.235). Thus
  444.        the C atoi() or atof() functions should be used to convert to integer
  445.        or floating form as required.
  446.  
  447.       Character
  448.       ---------
  449.  
  450.        Character fields are held internally as normal C format 0 terminated
  451.        strings.
  452.  
  453.       Logical
  454.       -------
  455.  
  456.        Logical fields are held as a single character string (0 terminated)
  457.        where the value is "T","t","Y", or "y"  for true values and
  458.        "F","f","N", or "n" for false values.
  459.  
  460.       Date
  461.       ----
  462.  
  463.        Date fields are held as character strings (0 terminated) of length 8.
  464.        These are in the form YYYYMMDD, thus 5th November 1962 is held as
  465.        "19621105".
  466.  
  467.       Memo
  468.       ----
  469.  
  470.        Memo fields are held as character strings which are 0 terminated,
  471.        they may be any length up to 64000 bytes provided there is sufficient
  472.        memory to hold them. Internally memos read from a database are held
  473.        in a buffer which starts at 512 bytes, and is expanded when necessary
  474.        to read a larger memo.
  475.  
  476.        Expression Evaluator
  477.        ====================
  478.  
  479.        The expression evaluator in the database library provides a complete
  480.        dBase compatible expression evaluation function which may be used to
  481.        select records, may be used for calculations on records, or is used
  482.        to create index expressions. The expression evaluator is associated
  483.        with the database object, and there is a public string (ers in the
  484.        database object) which holds the ASCII reperesentation of the last
  485.        database error which occurred, see the record::eval function for an
  486.        example.
  487.  
  488.        It provides the following operators which are shown in operator
  489.        precedence (those at the top of the list are executed first), note
  490.        that the dBase =< and => (which in dBase are equivalent to >= and <=)
  491.        are not implemented in the library (use the <= and >= operators
  492.        instead).
  493.  
  494.        ()      Parenthesis bracket operations and change the order of
  495.                evaluation.
  496.        +   -   Unary + and - operate on a single number.
  497.        **  ^   Exponentiation (to the power of)
  498.        *   /   Multiplication, Division
  499.        +   -   Add and Subtract, Numbers, Dates or Strings
  500.            Addition of two strings concatenates them. Subtraction on
  501.                strings takes the spaces from the end of the first string,
  502.                concatenates the second string to the first string, and then
  503.                puts the spaces back at the end of the new string.
  504.            A date may have a number added or subtracted from it which
  505.            provides a date which is that many days in the future or
  506.                past. A date may be subtracted from another date to give the
  507.                number of days between the two dates.
  508.        <
  509.        >
  510.        =
  511.        <> or #
  512.        <=
  513.        >=      These are relational operators and act on strings, dates, or
  514.                numbers to indicate if the first item is less than (<), less
  515.                than or equal to (<=), equal to (=), greater than (>),
  516.            greater than or equal (>=) or not equal (<>, or #) to the
  517.                second item. The first item must be of the same type as the
  518.            second item.
  519.        $       This is a string operator used in the form A$B, it returns
  520.            true if A is identical to B, or is contained within it.
  521.        .AND.   Logical AND.
  522.        .OR.    Logical OR.
  523.        .NOT.   Logical NOT, note the lower priority than .AND. and .OR.
  524.            which can be confusing to those used to conventional operator
  525.            precedence.
  526.  
  527.        Field names be used wherever a number, string or date may be used.
  528.  
  529.        e.g.
  530.  
  531.      database db("Names");
  532.      record rec(db);
  533.  
  534.      rec.select("upper(name)=\"B\"",FIRST);               // Select 1st
  535.      record where 1st character of name field is B
  536.      rec.select("ageyears+agemonths/12<12.5",NEXT);           // Select
  537.      next record where age is less than 12.5
  538.      rec.select("dob=ctod(\"17/4/78\")",FIRST);               // Select
  539.      1st record where dob field is 17th April 1978.
  540.  
  541.  
  542.       Expression Evaluator functions
  543.       ==============================
  544.  
  545.        The following functions are available:
  546.  
  547.        ABS(numeric expr)       Gives the absolute value of the supplied
  548.                    expression.
  549.        ASC(string expr)        Returns decimal ASCII value of the first 
  550.                                character of string
  551.        AT(char s1,char s2);    If string s1 is to be found in string s2 then
  552.                                this returrns the position that it is to be
  553.                                found at (starting at 1). it returns 0 if s2
  554.                                is not to be found in s1.
  555.        CDOW(date expr)         Returns a string which names the day of the
  556.                                week supplied by date expr.
  557.        CHR(numeric expr)       Gives a string of length 1 holding the
  558.                                character which has the ASCII code supplied
  559.                    by the numeric expression.
  560.        CMONTH                  Returns a string which names the month
  561.                                supplied by date expr.
  562.        CTOD(char expr)         Returns a date matching the character string
  563.                    supplied as input.
  564.        DATE()                  Returns the current operating system date.
  565.        DAY(date expr)          Returns the number of the day from the
  566.                                supplied date expression.
  567.        DOW(date expr)          Returns a number representing the day of the
  568.                                week from the supplied date expression.
  569.        DTOC(date expr)         Converts the date expression to a charcter
  570.                    string in system date format.
  571.        DTOS(date expr)         Gives the dBase date string form of date expr
  572.                                (YYYYMMDD). Note this function is dBase IV,
  573.                    not dBase III.
  574.        EXP(numeric expr)       Gives the result of e to the power numeric
  575.                                expr.
  576.        IIF(condition,expr1,expr2)  If condition is true returns the result
  577.                                of evaluating expr1, otherwise it returns the
  578.                                result of evaluating expr2.
  579.        INT(numeric expr)       Gives the integer value of the supplied
  580.                                expression.
  581.        ISALPHA(char expr)      Evaluates to TRUE if the 1st character of the
  582.                                supplied expression is a letter of the
  583.                                alphabet, FALSE if not.
  584.        ISDIGIT(char expr)      Evaluates to TRUE if the 1st character of the
  585.                                supplied expression is a number, FALSE if
  586.                                not.
  587.        ISLOWER(char expr)      Evaluates to TRUE if the 1st character of the
  588.                    supplied expression is a lower case letter of
  589.                                the alphabet, FALSE if not.
  590.        ISUPPER(char expr)      Evaluates to TRUE if the 1st character of the
  591.                                supplied expression is an upper case letter
  592.                    of the alphabet, FALSE if not.
  593.        LEFT(char expr,numeric expr)Returns the numeric expr characters from
  594.                                the left of the supplied string.
  595.        LEN(char expr)          Returns the length of the supplied character
  596.                                expression.
  597.        LOWER(char expr)        Returns a string where all letters of the
  598.                                supplied expression have been converted to
  599.                    lower case.
  600.        LTRIM(char expr)        Returns a string which is the supplied string
  601.                    with all leading spaces removed.
  602.        MAX(expr,expr)          Returns the greater of the two supplied
  603.                                numbers or dates.
  604.        MIN(expr,expr)          Returns the lesser of the two supplied
  605.                                numbers or dates.
  606.        MOD(numeric expr,numeric expr)  Gives the remainder when the first 
  607.                                        expression is divided by the second.
  608.        MONTH(date expr)        Returns the number of the month represented
  609.                                by the supplied date expression.
  610.        RECCOUNT()              Gives the number of records in the database.
  611.        RECNO()                 Gives the record number (in the dbf file)of
  612.                                the record on which the function is
  613.                                evaluated.
  614.        RECSIZE()               Gives the length of the records in the
  615.                                database.
  616.        REPLICATE(char expr,num expr)   Returns a string made by num expr 
  617.                        repeats of the supplied character
  618.                                        expression.
  619.        RIGHT(char expr, num expr)  Returns the numeric expr characters from
  620.                    the left of the supplied string.
  621.        ROUND(num expr,num dec) Gives the result of rounding off the supplied
  622.                    numeric expression to dec decimal places.
  623.        RTRIM(char expr)        (Same as TRIM).
  624.        SOUNDEX(char expr)      Gives the string of lenght 4 which results
  625.                    from running the SOUNDEX algorithm on the
  626.                    supplied character expression. Note that this
  627.                    is a dBase IV function and is not supported
  628.                    in dBase III.
  629.        SPACE(num expr)         Returns a string consisting of num expr space
  630.                    characters.
  631.        STR(number, len, decimal)   Returns the string which represents the
  632.                    number supplied. len is the total length of
  633.                    the resulting string, decimal is the number
  634.                    of decimal places.
  635.        STUFF(str 1,start,len,str 2)
  636.                    Gives a sting which is created by taking
  637.                    str 1, removing the substring which is
  638.                                defined by start and length, and inserting
  639.                                str2 where the substring was removed.
  640.        SUBSTR(string,start,length) Gives the string which is a substring of
  641.                                the supplied string starting at position
  642.                                start and going on for length characters. If
  643.                                length is not supplied then it returns the
  644.                                rest of the string. The string is assumed to
  645.                    start at position 1.
  646.        SWAPDATA(string)        This is a PCF function which takes the
  647.                    supplied string and takes the first ~
  648.                    character in it exchanging the information
  649.                    after the ~ for the information before it,
  650.                    and replacing the ~ by a space. Thus
  651.                    "SMITH~JOHN" becomes "JOHN SMITH". This is
  652.                    used in PCF for alphabetical sorting by
  653.                    surname but printing by proper name. This
  654.                    function is NOT dBase III compatible.
  655.        TIME()                  Gives the character representation of the
  656.                    current time.
  657.        TRIM(string expr)       Gives the string which results from removing
  658.                    all trailing spaces from the supplied string.
  659.        TYPE(expr)              Gives a single character string which
  660.                    represents the result type of expr. (C, N, L,
  661.                                or D). Note that unlike dBase date
  662.                                expressions are allowed, and that memo fields
  663.                                return C, not M like they would in dBase.
  664.        UPPER(string expr)      Returns a string where all letters of the
  665.                                supplied expression have been converted to
  666.                                upper case.
  667.        VAL(char expr)          Gives the numeric value of the expression
  668.                                contained in char expr. Note that the
  669.                                expression is a simple number thus "4.5"
  670.                                returns the number 4.5, but "9/5" returns the
  671.                                number 9.
  672.        YEAR(date expr)         Gives a four digit number which is the year
  673.                                of the date expression.
  674.  
  675.  
  676.       Examples
  677.       ========
  678.  
  679.       PACKDB
  680.       ======
  681.  
  682.        The following example shows a program which packs a database. That is
  683.        it takes an input database and creates an identical output database
  684.        which has deleted records removed. The program is invoked using the
  685.        command line:
  686.  
  687.        PACKDB INFILE OUTFILE [INDEX]
  688.  
  689.        INFILE is the name of the input database OUTFILE is the output
  690.        database which will be created. INDEX is the name of the optional
  691.        index file which will be used to order the input file so that the
  692.        records are written in this order to the output file.
  693.  
  694.        #include <stdio.h>
  695.        #include <stdlib.h>
  696.        #include <string.h>
  697.        #include <database.hpp>
  698.        #include <math.h>
  699.  
  700.        main(int argc, char *argv[])
  701.        {
  702.         char index[128];   // Holds index name if supplied
  703.         long i;
  704.  
  705.     if (argc<3)        // Error need at least two arguments
  706.         {
  707.          printf("\nUsage : packdb infile outfile [index]\n");
  708.          printf("\n\nDuplicates infile database to outfile database");
  709.      printf("\nremoving deleted records.\n\n");
  710.          printf("\nindex if supplied will operate on infile to define\n");
  711.          printf("\nthe order records are written to outfile\n\n");
  712.          exit(1);
  713.         }
  714.     if (argc==4) strcpy(index,argv[3]); else *index=0;    // Copy index
  715.  
  716.         database *dbin=new database(argv[1],index);   // Open input database
  717.         database *dbout=new database();               // Create new output
  718.                    database
  719.  
  720.         if (dbin->isvalid())       // Check if input database is valid
  721.         {
  722.          delete dbin; delete dbout;
  723.          printf("\nUnable to open input database, error %d\n\n",dbin-
  724.                    >isvalid());
  725.          exit(1);
  726.         }
  727.  
  728.         for(i=1; i<=dbin->getnfield(); i++)    // Copy all fields
  729.          dbout->addfield(dbin->getfield(i));
  730.  
  731.     if (dbout->write(argv[2])) // Check database successfully written
  732.     {
  733.      delete dbin; delete dbout;
  734.      printf("\nUnable to open output database\n\n");
  735.      exit(2);
  736.     }
  737.  
  738.     record *reci=new record(*dbin);        // Record on old database
  739.     record *reco=new record(*dbout);   // Record on new database
  740.  
  741.     long recn=1;
  742.     printf("\n");
  743.     int rv=reci->select(FIRST);        // set to 1st record (default
  744.            undeleted)
  745.         while(!rv)
  746.         {
  747.          for(i=1; i<=dbin->getnfield(); i++)       // Copy all fields
  748.          {
  749.           if (dbin->getfield(i)->gettype()=='N')   // Numeric fields
  750.           {
  751.            reco->setfield(i,atof(reci->getfield(i)));
  752.           }
  753.           else reco->setfield(i,reci->getfield(i));   // All other fields
  754.          }
  755.          reco->write(NEW);             // Write new record
  756.          rv=reci->select(NEXT);            // Next input record
  757.          printf("\r%ld",recn++);
  758.         }
  759.  
  760.         delete reci;
  761.         delete reco;
  762.         delete dbin;
  763.     delete dbout;
  764.         printf("\n\nOperation complete\n");
  765.        }
  766.  
  767.       FAMILYS
  768.       =======
  769.  
  770.        The second example below shows the use of sub totals. This example is
  771.        on a database of families which has been indexed on the field name
  772.        SURNAME. The program finds all records which have the SURNAME field
  773.        set to the same value in the database and works out the average of
  774.        the field called AGE (age in years) and AGEM (age in months) within
  775.        the family. It then returns and for every member of the family
  776.        updates the avgage field which is the difference between the AGE and
  777.        AGEM fields in the record and the average age worked out for the
  778.        family.
  779.  
  780.        /*
  781.           Demonstration of Subtotals,
  782.  
  783.           Short program to update average age for each family in familys.dbf
  784.           The average age is a field in each record which will indicate how
  785.                    far
  786.           away each family member is in age from the average age in that
  787.                    family
  788.  
  789.           Index expression in familys.ndx is :
  790.  
  791.             UPPER(SURNAME)
  792.  
  793.           Thus all family members will be grouped together
  794.        */
  795.  
  796.        #include <string.h>
  797.        #include <database.hpp>
  798.        #include <stdio.h>
  799.        #include <stdlib.h>
  800.        #include <math.h>
  801.  
  802.        void main()
  803.        {
  804.         char ws[128];           // Workspace
  805.  
  806.         database db("familys","familys");      // Open database
  807.         record rec(db);                    // Current record
  808.         record first(db);                             // Used to save
  809.                    position
  810.         int fn=db.getfield("avgage")->getnumber();        // Field no.
  811.                    avgage field
  812.  
  813.         int sel=rec.select(FIRST);     // Select first record
  814.         do
  815.         {
  816.          char surname[128];        // Holds current surname
  817.          double avgage=0;          // Holds average age
  818.          first=rec;                // Save position
  819.          int ssel=sel;         // save sel at current position
  820.          int trec=0;               // Total no. of records in patrol
  821.      strcpy(surname,rec.getfield("surname"));          // Copy in patrol
  822.                    name
  823.  
  824.          while(!sel && !strcmp(surname,rec.getfield("surname"))) // Until
  825.            new name
  826.      {
  827.           avgage+=atof(rec.getfield("age"))+atof(rec.getfield("agem"))/12;
  828.           trec++;
  829.           sel=rec.select(NEXT);            // On to next record
  830.          }
  831.          avgage/=trec;
  832.  
  833.          while(!ssel && !strcmp(surname,first.getfield("surname")))  //
  834.                    Round again
  835.          {
  836.           double age;
  837.  
  838.           age=atof(first.getfield("age"))+atof(first.getfield("agem"))/12;
  839.           first.setfield(fn,int(age-avgage));
  840.           first.write();           // Write the new record
  841.           ssel=first.select(NEXT);
  842.          }
  843.          printf("\nAverage age of %s is %f",surname,avgage);
  844.         }
  845.         while(!sel);
  846.        }
  847.  
  848.       DBRPT
  849.       =====
  850.  
  851.        The following program takes a database and prints a report on it,
  852.        printing number and length of records, and type and length of each
  853.        file. With the -c option it will print an include file for use in a
  854.        C++ program which contains "#define" statements for each field
  855.        number.
  856.  
  857.        It takes one argument, the file name with an optional -c to print the
  858.        the include file.
  859.  
  860.  
  861.        #include <stdio.h>
  862.        #include <stdlib.h>
  863.        #include <string.h>
  864.        #include <database.hpp>
  865.  
  866.        main(int argc, char *argv[])
  867.        {
  868.         char *wsp,ws[128]; // Useful work space
  869.         int inc=0;         // Flags results are to be printed in #include
  870.        form
  871.  
  872.         if (argc<2)            // Must have at least one parameter
  873.         {
  874.          printf("Usage : dbrpt filename [-c]\n");
  875.      printf("        -c option -> #include form for header files\n");
  876.      exit(1);
  877.         }
  878.         if (argc>2) if (!strcmpl(argv[2],"-c")) inc=1;
  879.  
  880.         strcpy(ws,argv[1]); strupr(ws);
  881.         if (wsp=strchr(ws,'.')) *wsp=0; if (wsp=strchr(ws,'\\')) *wsp=0;
  882.  
  883.     // Open database
  884.  
  885.         database *db=new database(argv[1]);
  886.         if (db->isvalid())             // Check if failed to open
  887.         {
  888.          delete db;
  889.          printf("\nError on opening database !"); exit(1);
  890.         }
  891.  
  892.         // Dump database stats.
  893.  
  894.         if (inc) printf("// Database %s, include file\n\n// ",ws);
  895.         else printf("\n");
  896.         printf("Database : %s has %ld records of length %d with %d
  897.        fields\n",
  898.            ws,db->getnrec(),db->getreclen(),db->getnfield());
  899.  
  900.         // Dump field stats for each field
  901.  
  902.         for(int i=1; i<=db->getnfield(); i++)
  903.         {
  904.      field *fld;
  905.  
  906.      fld=db->getfield(i);
  907.      if (inc) printf("\n#define %-10s %3d   // ",fld->getname(),i);
  908.      else printf("\nField %3d - %-10s ",i,fld->getname());
  909.      printf("Type %c, Length %3d, Rdp %d",
  910.          fld->gettype(),fld->getlen(),fld->getrdp());
  911.     }
  912.  
  913.     printf("\n\n");
  914.     delete db;
  915.     exit(0);
  916.        }
  917.  
  918.       Global Utility Functions
  919.       ========================
  920.  
  921.        The following are global functions available under the database
  922.        library, they may be of use in any database application.
  923.  
  924.       char *getdate(time_t time);
  925.  
  926.        This function obtains a time in the dbf form from an ANSI C time, the
  927.        returned string is static and is overwritten by each call to getdate.
  928.        Thus the current date can be obtained by:
  929.  
  930.                #include <time.h>
  931.                #include <database.hpp>
  932.  
  933.                time_t ntime;
  934.                time(&ntime);
  935.                char *dp=getdate(ntime);
  936.  
  937.       time_t gettime(char *string);
  938.  
  939.        This function obtains a time in the form used by the ANSI time
  940.        functions (e.g. asctime() etc). The string should be in dBase form,
  941.        YYYYMMDD.
  942.  
  943.       void gnums(char *date,int &d,int &m,int &y);
  944.  
  945.        This function takes the supplied date and returns the day, month and
  946.        year functions in the variables d,m and y. See the first example
  947.        shown above.
  948.  
  949.       char *ltrim(char *string);
  950.  
  951.        This function returns a pointer to the first character in string
  952.        which is not a space.
  953.  
  954.       char *soundex(char *dest,char *src);
  955.  
  956.        This function runs the soundex algorithm on the string src and places
  957.        the 4 character result in dest which is returned by the function.
  958.  
  959.       int strcmpdb(char *s1,char *s2,int len=-1);
  960.  
  961.        Compare strings using the dBase compare format. (i.e. "Bancroft"="B"
  962.        returns TRUE, "B"="Bancroft") returns false. len is the maximum
  963.        length to be compared, if -1 is supplied then the whole of s1 is
  964.        examined.
  965.  
  966.       char *swapdata(char *dest,int schar='~');
  967.  
  968.        This is a PCF function which takes the supplied string and takes the
  969.        first ~ (or whichever character is defined by schar) character in it
  970.        exchanging the information after the ~ for the information before it,
  971.        and replacing the ~ by a space. Thus "SMITH~JOHN" becomes "JOHN
  972.        SMITH". This is used in PCF for alphabetical sorting by surname but
  973.        printing by proper name. The function returns a pointer to dest.
  974.  
  975.       char *trim(char *string)
  976.       char *rtrim(char *string)
  977.  
  978.        These functions which are identical trim all trailing spaces from the
  979.        supplied string and return a pointer to it.
  980.  
  981.  
  982.       Classes
  983.       =======
  984.  
  985.        The following are the classes which make up the library , and their
  986.        associated member functions and variables.
  987.  
  988.  
  989.  
  990.  
  991.        database::database
  992.  
  993.  
  994.                void database::database();
  995.  
  996.  
  997.  
  998.        Description :   This constructor creates a database object with no
  999.                    fields and no records. The valid flag is set to -1 to
  1000.                    indicate that the database has not yet been written to
  1001.                    disk. Fields may be added to the database using the
  1002.                    database::addfield() function. Before records may be
  1003.                    written or read to or from the database then the
  1004.                    database::write() function is used to establish it on
  1005.                    disk.
  1006.  
  1007.  
  1008.        E.G.        // Create a database : "CLUB" with three fields, name
  1009.                    (character)
  1010.                    // dob (date), and phone (character)
  1011.  
  1012.                    #include <database.hpp>
  1013.  
  1014.                    database db();
  1015.  
  1016.                    db->addfield("NAME",'C',15);           // Name field
  1017.            db->addfield("DOB",'D');           // DOB field
  1018.            db->addfield("PHONE",'C',11);      // Phone Field
  1019.  
  1020.                    db->write("CLUB");
  1021.  
  1022.  
  1023.  
  1024.  
  1025.  
  1026.  
  1027.        database::database
  1028.  
  1029.  
  1030.                void database::database(char *name,char *index=0);
  1031.  
  1032.  
  1033.  
  1034.        Description :   This constructor opens an existing database which may
  1035.                    have 0 or more records.
  1036.  
  1037.                    The database constructor requires a file name for the
  1038.                    database, and an optional file name for the dBase
  1039.                    compatible index. If the index file name is supplied as
  1040.                    an empty string, or if the index file cannot be opened,
  1041.                    then each record follows the last in the database file.
  1042.                    If an index file name is supplied then each record
  1043.                    follows the last according to the index file sequence.
  1044.                    After the constructor is called the database::isvalid()
  1045.            function may be called to determine if the database was
  1046.            successfully opened. Additional indexes may be added
  1047.                    using the database::addindex() function
  1048.  
  1049.                    The database filename is assumed to have a ".DBF"
  1050.                    extension if none is supplied, and the index filename a
  1051.                    ".NDX" extension. If the database has an associated memo
  1052.                    file (.DBT extension) then this file is also opened.
  1053.  
  1054.                    The constructor automatically creates and initialises a
  1055.                    linked list of field objects which describes the fields
  1056.                    of the database.
  1057.  
  1058.                    Should the constructor fail then the database::isvalid()
  1059.                    function will report the error, returing 0 on success.
  1060.  
  1061.  
  1062.  
  1063.  
  1064.        E.G.        #include <database.hpp>
  1065.  
  1066.                    database *db;
  1067.  
  1068.                    db=new database("MEMBERS","NAME");
  1069.                    cout << *db;
  1070.  
  1071.  
  1072.  
  1073.  
  1074.  
  1075.  
  1076.        database::Accessor Functions
  1077.  
  1078.  
  1079.                long database::getnrec(void)
  1080.  
  1081.            unsigned int database::getreclen(void);
  1082.  
  1083.            char *getindkey(name);
  1084.  
  1085.            int getindkey(name);
  1086.  
  1087.            int database::getnfield(void);
  1088.  
  1089.            field *database::getfield(int n);
  1090.  
  1091.            void database::getversion(int &major,int &minor);
  1092.  
  1093.            field *database::getfield(char *name);
  1094.  
  1095.            int database::isvalid(void);
  1096.  
  1097.  
  1098.  
  1099.        Description : These are the accessor functions for the database, and
  1100.                    return various parameters about it.
  1101.  
  1102.  
  1103.                char *database::getindkey(char *name)
  1104.  
  1105.                This function returns the key on the index which has the
  1106.                supplied file name. name should not have a .NDX extension.
  1107.                The key should be copied if any modification is to be made to
  1108.                it. It returns 0 if no index of that name exists.
  1109.  
  1110.                int database::getindtype(char *name)
  1111.  
  1112.                This function returns the type of index for the index which
  1113.                has the supplied file name. name should not have a .NDX
  1114.                extension. The returned value is either OPINT or OPSTR
  1115.                depending on whether it is an integer or string index
  1116.                expression. It returns 0 if no index of the supplied name
  1117.                exists.
  1118.  
  1119.  
  1120.  
  1121.  
  1122.  
  1123.            int database::getnfield(void);
  1124.  
  1125.            This function returns the number of fields in the database.
  1126.  
  1127.            long database::getnrec(void)
  1128.  
  1129.            This function returns the number of records in the database.
  1130.  
  1131.            unsigned int database::getreclen(void);
  1132.  
  1133.            This function returns the record length of records in the
  1134.            database.
  1135.  
  1136.            void database::getversion(int &major,int &minor);
  1137.  
  1138.            This function sets major to the major number of the database
  1139.            library version and minor to the minor number. For instance
  1140.            version 2.3 will set major to 2, and minor to 3.
  1141.  
  1142.            int database::isvalid(void);
  1143.  
  1144.            This function returns a code which represents the state of
  1145.            the database object. The code takes on the following values:
  1146.  
  1147.            -2              Creating Database with a memo field, not yet
  1148.            written to      disk
  1149.                -1              Creating Database, not yet written to disk
  1150.            0               Database file opened and initialised
  1151.                successfully.
  1152.                NOFILE          Database file could not be opened.
  1153.            NOINDEX         Index file could not be opened.
  1154.                NOMEM           Memory allocation error on database creation.
  1155.  
  1156.        E.G.        #include <database.hpp>
  1157.  
  1158.  
  1159.  
  1160.                    database db("CLUB","")
  1161.  
  1162.                    printf("Database has :\n");
  1163.                    printf("%d Records\n",db.getnrec());
  1164.                    printf("%d Fields\n",db.getnfields());
  1165.  
  1166.  
  1167.  
  1168.  
  1169.  
  1170.  
  1171.        database::addfield
  1172.  
  1173.  
  1174.                int database::addfield(char *name,int type,int length=1,int
  1175.                rdp=0);
  1176.  
  1177.                int database::addfield(field *fp);
  1178.  
  1179.  
  1180.  
  1181.        Description :   This function adds a field to a database which is
  1182.            being created.
  1183.  
  1184.                    The first form of the function adds a defined field. name
  1185.                    is the name of the field, type is the field type -
  1186.            'C','D','M','L' , or 'N'. Length is defined for character
  1187.                    and numeric fields and is the length of these fields in
  1188.                    the database. The other field types are set automatically
  1189.                    and the length parameter is ignored. The rdp parameter is
  1190.            only used by numeric fields to set the number of decimal
  1191.                    places in the field.
  1192.  
  1193.                    The second form of the function makes a new field from a
  1194.                    pointer to an existing field from an existing (but
  1195.                    different) database.
  1196.  
  1197.                    The function returns 0 if successful, DUPFIELD if the
  1198.                    name of this field exists in the database already, and
  1199.                    INVFIELD if a different error occurs.
  1200.  
  1201.  
  1202.        E.G.        See the database::database() function.
  1203.  
  1204.  
  1205.  
  1206.  
  1207.  
  1208.  
  1209.        database::addindex
  1210.  
  1211.  
  1212.                field *database::addindex(char *filename);
  1213.  
  1214.  
  1215.  
  1216.        Description :   This function adds an index to the list of indexes
  1217.                    which is maintained for each database. When an index is
  1218.                    added it is available for use by records which may select
  1219.            any index, which then defines the order in which records
  1220.                    are read from the database. Any index attached to a
  1221.                    database is automatically updated as records are modified
  1222.                    or added within the database. The file name is assumed to
  1223.                    have a .NDX extension.
  1224.  
  1225.                    Functions such as the record constructor which require to
  1226.                    identify an index on the database use the name defined in
  1227.                    the database constructor or the database::addindex()
  1228.                    function. Thus the index "NAME.NDX" is referred to as
  1229.                    "NAME" in functions which need to identify an index.
  1230.  
  1231.                    The function returns 0 if the index is successfully
  1232.                    attached to the database, and the error NOINDEX if the
  1233.                    file could not be opened. It returns the error INVIND if
  1234.                    there is an error in the index file or if it is already
  1235.                    attached. Index file checking is limited and will not
  1236.                    spot all types of index file corruption.
  1237.  
  1238.  
  1239.        E.G.        #include <database.hpp>
  1240.  
  1241.                    database *db;
  1242.  
  1243.                    db=new database("MEMBERS","AGE");
  1244.                    db.addindex("AGE");
  1245.                    db.addindex("FUNC");
  1246.                    db.addindex("PHDIG");
  1247.  
  1248.            record rec(db,"FUNC");      // rec uses the FUNC index
  1249.  
  1250.  
  1251.  
  1252.  
  1253.  
  1254.  
  1255.        database::buildindex
  1256.  
  1257.  
  1258.            void database::buildindex(char *expr,char *filename,
  1259.                      void (*progress)(int s,long e)=0,
  1260.                      int order=250);
  1261.  
  1262.  
  1263.  
  1264.        Description :   This function constructs a new index on the database.
  1265.            expr is the expression that is to be used for the index
  1266.            file, it must be a valid index expression. filename is
  1267.            the name of the index file to be written, if a file
  1268.            exists it will be overwritten. Index file creation may
  1269.            take some considerable time for a large database. After a
  1270.            successful creation the index can be attached to the
  1271.            database using the database::addindex() function if it is
  1272.            desired to use it immediately.
  1273.  
  1274.            progress is the optional address of a function which can
  1275.            show the progress of the index build, and can be used for
  1276.            example, to show a bar chart of % complete.
  1277.  
  1278.            The function progress will be called every order records
  1279.            (as default order=250). The function is called with an
  1280.            integer s, which is the stage of the build, and a long e,
  1281.            which is the event.
  1282.  
  1283.            Stage runs from 1 to 3. When stage is 1, then event will
  1284.            count from 1 to the N which is the number of records.
  1285.            When stage is 2 then event will count from 1 to a maximum
  1286.            value which is calculated as N/2*log(N)/log(2), however it
  1287.            may be a lot less depending on how well sorted the records
  1288.            are in the database. When stage is 3 then event will count
  1289.            from 1 to the number of index clusters, it is usually not
  1290.            worth displaying event when stage is 3, as it is so fast.
  1291.  
  1292.            You may find that there are periods in stage 2 of the
  1293.            build (which is the sorting phase), when event is updated
  1294.            very slowly (for instance the first update may take a long
  1295.            time). This is normal.
  1296.  
  1297.            buildindex returns 0 on success, or the error EXPRERR
  1298.            if an error occurred in expression evaluation on any
  1299.            record, or the error NOINDEX if the file could not be
  1300.            opened.
  1301.  
  1302.            The filename must not be already attached to the owning
  1303.            or any other database or the program will almost
  1304.            certainly crash.
  1305.  
  1306.  
  1307.        E.G.        #include <database.hpp>
  1308.  
  1309.  
  1310.           void prtbuild(int,long);
  1311.  
  1312.           database db=database("MEMBERS");
  1313.           db.buildindex("UPPER(NAME)","NAME",prtbuild);
  1314.           db.addindex("NAME");
  1315.  
  1316.           void prtbuild(int stage,long event)
  1317.           {
  1318.            printf("\rStage %d, Event %ld",stage,event);
  1319.           }
  1320.  
  1321.  
  1322.  
  1323.  
  1324.  
  1325.  
  1326.        database::getfield
  1327.  
  1328.  
  1329.            field *database::getfield(int n);
  1330.  
  1331.  
  1332.            field *database::getfield(char *name);
  1333.  
  1334.  
  1335.  
  1336.        Description :   These functions return a pointer to the field class
  1337.                    which is defined either by number n, or by its name. If
  1338.                    the field cannot be found a zero pointer is returned.
  1339.  
  1340.  
  1341.        E.G.        #include <database.hpp>
  1342.  
  1343.            field *fpt;
  1344.            database db("LIST","NAME");
  1345.  
  1346.            fpt=db.getfield("NAME");
  1347.            printf("\nName field is number : %d",fpt->getnumber());
  1348.            printf("\nName field is of length : %d",fpt->getlen());
  1349.  
  1350.  
  1351.  
  1352.  
  1353.  
  1354.  
  1355.        database::subindex
  1356.  
  1357.  
  1358.            int database::subindex(char *name);
  1359.  
  1360.  
  1361.  
  1362.        Description :   This function removes an index from the list of
  1363.            indexes which is maintained for each database. The name
  1364.            is the filename which was used to add the index (from the
  1365.            database::database() or database::addindex() functions).
  1366.  
  1367.            The function returns 0 on success, or the error NOINDEX
  1368.            if the index could not be found. It will return INDINUSE
  1369.            if a record is using the index and the index will not be
  1370.            removed.
  1371.  
  1372.  
  1373.  
  1374.  
  1375.  
  1376.  
  1377.        database::setdateformat
  1378.  
  1379.  
  1380.            void database::setdateformat(dates newform);
  1381.  
  1382.  
  1383.  
  1384.        Description :   This function sets the date format to be used by
  1385.             the expression evaluator. If newform is USDATE then
  1386.             the US date format is used, mm/dd/yyyy, if newform is
  1387.             UKDATE then the european date format is used :
  1388.             dd/mm/yyyy.
  1389.  
  1390.             The default is USDATE.
  1391.  
  1392.             E.G. db->setdateformat(UKDATE);
  1393.  
  1394.  
  1395.  
  1396.  
  1397.  
  1398.  
  1399.        database::write
  1400.  
  1401.  
  1402.            int database::write(char *filename);
  1403.  
  1404.  
  1405.  
  1406.        Description :   This function will write a database which is newly
  1407.            created to disk. filename is the name of the database
  1408.                    (without the .dbf extension) on disk. After this function
  1409.            has been executed successfully the database will be valid
  1410.                    (the valid flag will be 0), and records may be written
  1411.                    (and then read) on the database.
  1412.  
  1413.                    It returns 0 on success, or NOFILE if the database is not
  1414.            newly created or cannot be written to disk.
  1415.  
  1416.  
  1417.        E.G.        See the database::database() constructor function.
  1418.  
  1419.  
  1420.  
  1421.  
  1422.  
  1423.  
  1424.        database::verifyindex
  1425.  
  1426.  
  1427.            int database::verifyindex(char *indexname,int depth=1,
  1428.                      void (*progress)(int test,long rec)=0,
  1429.                      int order=100);
  1430.  
  1431.        Description :   This function will run through the entire database
  1432.            using the supplied index name which should already be
  1433.            attached to the database, and check that the index matches
  1434.            the records in the database.
  1435.  
  1436.            depth controls the thoroughness of the test. If depth is 1
  1437.            (the default), then about 1000 records are checked per
  1438.            second (on a 33MHz 486), and the test checks that the
  1439.            index holds the same number of records as the database.
  1440.            If depth is 2, then the order of records is checked, if
  1441.            depth is 3, then every record in the database is found
  1442.            in the index. Depth 2 and 3 are intended mainly for
  1443.            debugging, and are too slow for normal use.
  1444.  
  1445.            progress is the optional address of a function which can
  1446.            show the progress of the index verify, and can be used for
  1447.            example, to show a bar chart of % checked.
  1448.  
  1449.            The function progress will be called every order records
  1450.            (as default order=100). The function is called with an
  1451.            integer test, which is the stage of the verify, and a long r,
  1452.            which is the record number. r runs from 1 to the selected
  1453.            depth. r runs from 1 to the number of records in the
  1454.            database for each stage.
  1455.  
  1456.            verifyindex returns:
  1457.            0         if the index is OK.
  1458.            INCOMP     if the index appears to end before all records
  1459.                 have been read from the database, OORD if the
  1460.                 records are out of order
  1461.            RECNOTFND    if a record is not found in the index
  1462.            ERRINTREE     if the index tree has an error in it
  1463.            INVIND     if the index is not attached to the database,
  1464.                 or there is an error in the index expression.
  1465.  
  1466.  
  1467.        E.G.        database db("CLUB","NAME");
  1468.  
  1469.            if (db->verifyindex("NAME))     // On error rebuild index
  1470.            {
  1471.             db->subindex("name");
  1472.             db->buildindex("upper(name)","name");
  1473.             db->addindex("name");
  1474.            }
  1475.  
  1476.  
  1477.  
  1478.  
  1479.  
  1480.  
  1481.        field::Accessor Functions
  1482.  
  1483.  
  1484.            int field::getlen();
  1485.  
  1486.  
  1487.            char *field::getname();
  1488.  
  1489.  
  1490.            int field::getnumber();
  1491.  
  1492.  
  1493.            int field::getrdp();
  1494.  
  1495.  
  1496.            char field::gettype();
  1497.  
  1498.  
  1499.  
  1500.        Description :   These functions return various information about the
  1501.            field object to which they are applied.
  1502.  
  1503.  
  1504.            int field::getlen();
  1505.  
  1506.  
  1507.                This returns the length of the field in characters.
  1508.  
  1509.  
  1510.                char *field::getname();
  1511.  
  1512.  
  1513.            This returns a pointer to the name of the field.
  1514.  
  1515.  
  1516.                int field::getnumber();
  1517.  
  1518.  
  1519.                This returns the number of the field.
  1520.  
  1521.  
  1522.                int field::getrdp();
  1523.  
  1524.  
  1525.                This returns the number of characters to the right of the
  1526.                decimal place in a numeric field.
  1527.  
  1528.  
  1529.  
  1530.  
  1531.  
  1532.                char field::gettype();
  1533.  
  1534.  
  1535.            This returns the single character field type which will be
  1536.            one of  C,N,D,L, or M. These have the following meanings :
  1537.  
  1538.  
  1539.            C          Character field
  1540.            N          Numeric field
  1541.            D          Date field
  1542.            L          Logical field
  1543.            M          Memo field
  1544.  
  1545.  
  1546.        E.G.        #include <database.hpp>
  1547.  
  1548.  
  1549.  
  1550.            field *fpt;
  1551.            database db("DATA","");
  1552.  
  1553.            fpt=db.getfield("DATE");
  1554.            cout << "Date field is number :" << fpt->getnumber();
  1555.            cout << " and of type " << fpt->gettype();
  1556.  
  1557.  
  1558.  
  1559.        See Also :
  1560.  
  1561.  
  1562.  
  1563.  
  1564.  
  1565.  
  1566.  
  1567.        record::record
  1568.  
  1569.  
  1570.                void record::record(class database &db, char *index=0);
  1571.  
  1572.  
  1573.  
  1574.        Description :   The record constructor is called with a database to
  1575.                    which the record object will belong. The object may then
  1576.                    hold any record from that database, and the extraction
  1577.                    functions may be used to obtain any of the fields from
  1578.                    the record. The selection functions are used to read a
  1579.                    required record into the object.
  1580.  
  1581.                    Note that the constructor reads no information into the
  1582.                    record, the record contents will be invalid until the
  1583.                    select functions are used.
  1584.  
  1585.                    index is the index to be used with this record. If no
  1586.                    indexes are in use, or if NOIND is supplied as the index
  1587.                    parameter then records are read from the database in the
  1588.                    order that they were written (this is fastest). If the
  1589.                    index is supplied as 0 then the first index attached to
  1590.            the database is used for this record, this will be
  1591.                    attached either by the database constructor, or by the
  1592.                    database::addindex() function. If the index is a name
  1593.                    then this is the one used.
  1594.  
  1595.                    The index name is the filename of the .NDX file without
  1596.                    the .NDX extension so the index file "name.ndx" is
  1597.            referred to as "name".
  1598.  
  1599.                    If the index cannot be opened then no index is associated
  1600.                    with the record.
  1601.  
  1602.  
  1603.        E.G.    #include <database.hpp>
  1604.  
  1605.                database db("EQUIP","TITLE");       // Database constructor
  1606.                db.addindex("AGE");         // Age index is attached
  1607.                db.addindex("NAME");        // Name index is attached
  1608.  
  1609.                record rec(db);            // Record uses "TITLE" index
  1610.                record rec1(db,NOIND);     // Record with no index
  1611.                record rec2(db,"AGE");     // Record uses "AGE" index
  1612.  
  1613.        See Also : record::select(), database::addindex(),
  1614.        database::database()
  1615.  
  1616.  
  1617.  
  1618.  
  1619.  
  1620.  
  1621.        record::Accessor Functions
  1622.  
  1623.  
  1624.                int record::getdelstate();
  1625.  
  1626.                long record::getrecnum();
  1627.  
  1628.                char *record::indname();
  1629.  
  1630.                int record::setdelstate(int state);
  1631.  
  1632.  
  1633.  
  1634.        Description :   These functions return information about the record
  1635.                    object.
  1636.  
  1637.  
  1638.                int record::getdelstate();
  1639.  
  1640.  
  1641.                This function returns the delete state of the record either,
  1642.                either DEL or NOTDEL.
  1643.  
  1644.  
  1645.                long record::getrecnum();
  1646.  
  1647.  
  1648.            This function returns the record number of the record object
  1649.                in the database.
  1650.  
  1651.  
  1652.                char *record::indname();
  1653.  
  1654.  
  1655.                This function returns the index name used on this record, or
  1656.                0 if none.
  1657.  
  1658.  
  1659.                void record::setdelstate(int state);
  1660.  
  1661.  
  1662.                This setes the delete state of the record, to deleted
  1663.                (state==DEL), or not deleted (state==NOTDEL). Note that the
  1664.                record in the dbf file is not updated until a record::write()
  1665.                function is executed.
  1666.  
  1667.  
  1668.  
  1669.  
  1670.  
  1671.  
  1672.        record::eval
  1673.  
  1674.  
  1675.                void record::eval(char *expr,void *result,int &rtype);
  1676.  
  1677.  
  1678.                void record::eval(void *result,int &rtype);
  1679.  
  1680.  
  1681.  
  1682.        Description :           These functions evaluate an expression which
  1683.                    is provided in ASCII (e.g. "age<12") and return a result.
  1684.                    The expression is evaluated on the current record and
  1685.                    values for fields in the expression are taken from the
  1686.                    current record.
  1687.  
  1688.                    When the function is called, the expression is tokenised
  1689.                    and stored internally. If the same expression is to be
  1690.                    evaluated more than once, then for the second and
  1691.                    subsequent calls the second form of the expression may be
  1692.                    used. This will result in faster evaluation, however the
  1693.                    tokenised form of the expression is overwritten by any
  1694.                    call to eval by any record, by the record::indchk()
  1695.                    function, by the index building functions (which are
  1696.                    called by database::addindex(), database::buildindex(),
  1697.                    and by adding a record to an indexed database), and by
  1698.                    the record select by expression function.
  1699.  
  1700.                    The function returns 0 if there was an error in the
  1701.                    evaluation in which case the owning database string ers
  1702.                    may be checked for an ASCII representation of the error.
  1703.                    On success the function returns 1.
  1704.  
  1705.                    result points to an area of memory into which is written
  1706.            the result of the evaluation. rtype represents the type
  1707.                    of the result:
  1708.  
  1709.            rtype       Result Type     result points to :
  1710.  
  1711.                    1 (OPINT)   Numeric         A double
  1712.                    2 (OPSTR)   String          A string
  1713.                    4 (OPDATE)  Date            An 8 character string in
  1714.                    dBase data format
  1715.                    8 (OPLOG)   Logical         Single character string - F
  1716.                    or T.
  1717.  
  1718.                    Memo fields may be used freely in expression, however the
  1719.                    expression evaluator maintains its own memory area which
  1720.                    may overflow if results of string expressions are too
  1721.                    long. Memo fields are stored in a buffer which may be
  1722.                    modified by the evaluator, see the record::getfield
  1723.                    function for a further discussion of this.
  1724.  
  1725.  
  1726.  
  1727.  
  1728.  
  1729.        E.G.        // Print the age in years from the dob field
  1730.                    // in the database (date of birth) and the current date.
  1731.                    // Print for all those whose name begins with "A"
  1732.  
  1733.                    database db("CLUB");
  1734.                    record rec(db);
  1735.  
  1736.                    int sel=rec.select("name\"A\"",FIRST);
  1737.  
  1738.                    while(!sel) // For all records
  1739.                    {
  1740.                     char result[128];      // Holds result
  1741.                     int dum;               // Dummy variable
  1742.  
  1743.                     cout << "\n" << (char *)rec.getfield("name") << "is ";
  1744.                     int rv=rec.eval("int((date()-dob/365.25)",result,dum);
  1745.                     if (!rv)
  1746.                     {
  1747.                      cout << "Couldn't calculate result because :";
  1748.                      cout << db.ers;
  1749.                     }
  1750.                     else cout << *(double *)result << " years old";
  1751.  
  1752.                     sel=rec.select("name=\"A\"",NEXT);
  1753.                    }
  1754.  
  1755.  
  1756.  
  1757.  
  1758.  
  1759.  
  1760.        record::getfield
  1761.  
  1762.  
  1763.                void record::getfield(int n,int trimflag=1);
  1764.  
  1765.  
  1766.                void record::getfield(char *name,int trimflag=1);
  1767.  
  1768.  
  1769.  
  1770.        Description :               These functions return a pointer to (a
  1771.                    copy of) the specified field. n is the field number (the
  1772.                    first field is number 1), or the field can be specified
  1773.                    by name. It should be noted that it is much faster to
  1774.                    obtain a field by number than by name as the latter
  1775.                    requres a search of all field names in the current data
  1776.                    base.
  1777.  
  1778.                    Note that the string returned is not guaranteed to be
  1779.                    maintained through further calls to the database library
  1780.                    functions, so a copy should be made if it is required to
  1781.                    maintain the field value through other functions. The
  1782.                    function returns a string of spaces if the field cannot
  1783.                    be found, or if a record has not been read with one of
  1784.                    the select functions.
  1785.  
  1786.                    If trimflag is 1 then results are trimmed, that is
  1787.                    trailing spaces are removed, if it is 0 then the field is
  1788.                    returned as is.
  1789.  
  1790.                    The return values of the function are the internal form
  1791.                    held in dbf files, thus the string will have the
  1792.                    following types:
  1793.  
  1794.                    FIELD TYPE      FORMAT
  1795.  
  1796.                    Character       Zero terminated string form of field.
  1797.                    Numeric         ASCII representation of number, use
  1798.                    atoi() or atof() to obtain
  1799.                                    number in integer or floating point form.
  1800.                    Date            String form of date  : YYYYMMDD, thus
  1801.                    19/11/1965 is held as
  1802.                                    19651119. Use the gettime() function to
  1803.                    return
  1804.                                    an ANSI time in seconds which may be used
  1805.                    with ANSI C time
  1806.                                    functions.
  1807.                    Logical         The return value is a single character
  1808.                    which holds T,t,Y,y for TRUE    and F, f, N, or n for
  1809.                    FALSE.
  1810.                    Memo            Returns a pointer to a buffer which holds
  1811.                    the memo in standard    string format, see below.
  1812.  
  1813.  
  1814.  
  1815.  
  1816.  
  1817.        Memos:      Memo fields are held in a buffer which is initially 512
  1818.                    bytes long, but is increased in length as required as
  1819.                    bigger memos are found. Not that there is only one memo
  1820.                    buffer per database, and it is overwritten every time
  1821.            that a memo field is accessed from any record. Expression
  1822.            which act on memo fields may also modify this buffer.
  1823.                    Thus it is important that if it is desired to keep the
  1824.                    memo field intact through other database function calls
  1825.                    then the buffer should be copied. The buffer (and
  1826.                    therefore any memo field) has a maximum length of 64k.
  1827.                    Empty memos return a null string.
  1828.  
  1829.  
  1830.        E.G.        see record::select
  1831.  
  1832.  
  1833.  
  1834.  
  1835.  
  1836.  
  1837.        record::indchk
  1838.  
  1839.  
  1840.                int record::indchk(char *expr,int &rtype);
  1841.  
  1842.  
  1843.  
  1844.        Description:    This function checks the supplied expression and
  1845.                    returns the length of the result in an index expression
  1846.                    (e.g. trim(name) has a length which is the same as the
  1847.                    length of the name field). If the expression is not valid
  1848.                    for an index (e.g. it's result length exceeds 100
  1849.            characters, the result is logical, or there is an error
  1850.                    in the expression etc.) then the function returns 0, and
  1851.            the ers string in the database is set to the error
  1852.                    report. rtype is set to the type of the expression which
  1853.                    takes the same values as the rtype parameter in the
  1854.                    record::eval() function.
  1855.  
  1856.  
  1857.        E.G.        database db("Names","CNAME");
  1858.                    record rec(db);
  1859.  
  1860.                    int rt;
  1861.                    int indval=rec.indchk(exprt,rt);
  1862.  
  1863.                    if (!indval)
  1864.                     printf("\n %s is not a valid index because
  1865.                    %s",exprt,rec.db.ers);
  1866.  
  1867.  
  1868.  
  1869.  
  1870.  
  1871.  
  1872.        record::seldbf
  1873.  
  1874.  
  1875.                int record::seldbf(long n);
  1876.  
  1877.  
  1878.  
  1879.        Description:    This function sets the record to record number n in
  1880.            the dbf file regardless of any index file in current use,
  1881.                    or the state of the record (deleted or not). Note that
  1882.                    the first record is record 1.
  1883.  
  1884.                    It returns 0 on success, or CANTSEL if n is out of range.
  1885.  
  1886.                    After this function the record::select() functions may
  1887.                    give unpredictable results unless the
  1888.                    record::select(..FIRST) function is used.
  1889.  
  1890.  
  1891.        See Also:   record::select()
  1892.  
  1893.  
  1894.  
  1895.  
  1896.  
  1897.  
  1898.        record::select
  1899.  
  1900.  
  1901.                int record::select(long n,int type=NOTDEL);
  1902.  
  1903.  
  1904.                int record::select(int fieldnum,int value,long n,int
  1905.            type=NOTDEL);
  1906.  
  1907.  
  1908.                int record::select(int fieldnum,char *value,long n,int
  1909.            type=NOTDEL);
  1910.  
  1911.  
  1912.                int record::select(int fieldnum,void *value,int (*cmp)(void
  1913.                *,void *),long n,int type=NOTDEL);
  1914.  
  1915.  
  1916.                int record::select(char *expr,long n,int type=NOTDEL);
  1917.  
  1918.  
  1919.  
  1920.        Description :           These functions update the record structure
  1921.                    to contain the selected record from the database. The
  1922.                    first function record::select(n) simply selects a record
  1923.                    without regard to the contents of the record, the others
  1924.                    select record by some criteria. The type parameter may be
  1925.                    supplied as NOTDEL, DEL or ALL, this defines whether
  1926.                    deleted, not deleted, or all records which match the
  1927.                    criteria are retrieved.
  1928.  
  1929.  
  1930.  
  1931.  
  1932.                    The second form selects records where the specified field
  1933.            number which is assumed to be numeric, matches the
  1934.                    supplied integer value. The third form selects record
  1935.                    where the specified field number matches the supplied
  1936.                    string. The fourth form allows the user to supply a
  1937.                    function which searches for records. The function takes
  1938.            two pointers, the first will be supplied as a string from
  1939.                    the record (this is the value of the specified field),
  1940.                    the second pointer is to the value supplied to the
  1941.                    function.The function should return 0 if it has found a
  1942.                    valid record.
  1943.  
  1944.                    The final form takes a dBase expression which should
  1945.                    return a logical value (e.g. "age<12") and returns all
  1946.                    records for which the expression returns a True value. If
  1947.                    the expression is supplied as "" then the last expression
  1948.                    which was evaluated is used. (Note that any library
  1949.                    function which uses the expression evaluator will modify
  1950.                    the last expression). If an error occurs in evaluation or
  1951.                    a non-logical value is returned, then this function
  1952.                    returns CANTSEL.
  1953.  
  1954.  
  1955.  
  1956.  
  1957.  
  1958.                    The functions read a record from the database according
  1959.                    to the value supplied in n, and then allows the user to
  1960.                    access the fields in that record using the record
  1961.            accessor functions. The function returns 0 is it was
  1962.                    successful, and the error CANTSEL if it failed.
  1963.                    If an index is in use then the record order specified in
  1964.                    the index file is used by the select functions.
  1965.  
  1966.                    If n is greater than 0 then it is the record number to be
  1967.            loaded, note that the first record is record number 1.
  1968.                    The record number n is the nth record which matches the
  1969.                    selection criteria, not the record number in the dbf
  1970.                    file, use the record::seldbf() function is select the nth
  1971.                    record in the dbf file.
  1972.  
  1973.  
  1974.  
  1975.                    If n is less than 0 then it takes the values FIRST, LAST,
  1976.                    NEXT or PREVIOUS. These values have the following
  1977.                    meanings:
  1978.  
  1979.                    FIRST       The first record which matches the criteria
  1980.                    is loaded.
  1981.                    LAST        The last record is loaded.
  1982.                    NEXT        The next record in sequence is loaded.
  1983.                    PREVIOUS    The previous record in sequence is loaded.
  1984.  
  1985.  
  1986.  
  1987.  
  1988.  
  1989.        E.G.        #include <database.hpp>
  1990.  
  1991.                    int compfirst(void *,void *);
  1992.  
  1993.                    /*******************************/
  1994.                    /* Print all names in database */
  1995.  
  1996.            void main()
  1997.                    {
  1998.                     database db("MEMBERS","SERIAL");
  1999.  
  2000.                     record rec(db);
  2001.  
  2002.                     int sel;
  2003.  
  2004.                     sel=rec.select(FIRST);
  2005.                     while (!sel)
  2006.                     {
  2007.                      printf("%s\n",rec.getfield("NAME"));
  2008.                      sel=rec.select(NEXT);
  2009.                     }
  2010.  
  2011.                     /*********************************************/
  2012.                     /* Find all members whose name begins with C */
  2013.  
  2014.                     fieldnum=(db.getfield("NAME"))->number;
  2015.  
  2016.                     int rv=rec.select(fieldnum,"C",compfirst,FIRST);
  2017.             while(!rv)
  2018.                     {
  2019.                      printf("%s\n",rec.getfield(fieldnum));
  2020.                      rv=rec.select(fieldnum,"C",compfirst,NEXT);
  2021.                     }
  2022.                    }
  2023.  
  2024.                    /***************************************************/
  2025.            /* This function compares two strings and returns  */
  2026.                    /* zero if the first characters are the same       */
  2027.  
  2028.                    int compfirst(void *name,void *value)
  2029.                    {
  2030.                     return(*(char *)name!=*(char *)value);
  2031.                    }
  2032.  
  2033.        See Also : record::getfield()
  2034.  
  2035.  
  2036.  
  2037.  
  2038.  
  2039.  
  2040.        record::selkey
  2041.  
  2042.  
  2043.                int record::selkey(char *value,int type=NOTDEL);
  2044.  
  2045.            int record::selkey(double value,int type=NOTDEL);
  2046.  
  2047.                int record::selkey();
  2048.  
  2049.  
  2050.  
  2051.        Description :   This function selects the record by the index key
  2052.                    attached to the record. value is the key value to find
  2053.            and is the result of the index expression on the record
  2054.            which will be matched to the record to find it in the
  2055.                    database. type is either DEL, NOTDEL or ALL and has the
  2056.                    same meanings as in the record::select() functions.
  2057.  
  2058.                    The final form of the function (record::selkey()) selects
  2059.                    records with the same key as supplied previously.
  2060.  
  2061.                    Selecting by key (when known) is much faster than using
  2062.                    the record::select() functions, although the right index
  2063.                    should be used.
  2064.  
  2065.                    It returns with 0 on success, NOKEY if record key could
  2066.                    not be found and in this case will select the record with
  2067.                    the next highest key, if there is no higher key then it
  2068.                    returns NOKEYHIGHER, and selects the last record by
  2069.                    index.
  2070.  
  2071.                    If there is no index it returns CANTSEL.
  2072.  
  2073.            The record::select() functions may be used with NEXT and
  2074.                    PREVIOUS parameters after this function is used if
  2075.                    required.
  2076.  
  2077.  
  2078.        E.G.        // Find all records where name starts with B
  2079.  
  2080.                    record rec(*db,"Name");            // Use name index
  2081.  
  2082.                    int sel=rec.selkey("B");
  2083.  
  2084.                    while(!sel)
  2085.                    {
  2086.                     printf("\n%s",rec.getfield("name"));
  2087.                     sel=rec.selkey();
  2088.                    }
  2089.  
  2090.  
  2091.  
  2092.  
  2093.  
  2094.  
  2095.        record::setfield
  2096.  
  2097.  
  2098.            int record::setfield(char *name,char *value);
  2099.  
  2100.                int record::setfield(char *name,double value);
  2101.  
  2102.            int record::setfield(int fieldnum,char *value);
  2103.  
  2104.            int record::setfield(int fieldnum,double value);
  2105.  
  2106.  
  2107.  
  2108.        Description :   Update a field in the record. The first two forms use
  2109.            the field name to set the field, the second two forms use
  2110.            fieldnum as the number of the field. The various forms of
  2111.            the function convert the argument types to a string and
  2112.            write this to the field. Date, Logical, Memo and
  2113.            Character fields should use the char * (as the 2nd
  2114.            parameter) form of the function, Numeric fields will use
  2115.            the double form. Date and Logical field values should be
  2116.            in dBase format (the getdate() function, described in the
  2117.            Functions part of this document, is useful here).
  2118.  
  2119.            Note that the record class is updated, but the database
  2120.            is not updated until a record::write() function is
  2121.            executed.
  2122.  
  2123.            The function returns 0 if the field is set to the value
  2124.            successfully, and RECNOTSET if an error occurred.
  2125.  
  2126.            The first field is field number 1 when the numeric version
  2127.            is used.
  2128.  
  2129.  
  2130.        Memo Fields:    Memo fields must provide a pointer to a buffer which
  2131.            should remain valid until the record is written. The old
  2132.            buffer in the memo file is overwritten if the new memo
  2133.            field will fit in the same space as the old one.
  2134.  
  2135.  
  2136.  
  2137.  
  2138.  
  2139.        E.G.        #include <database.hpp>
  2140.  
  2141.                    // Undelete all deleted records, and
  2142.                    // update a field which indicates the number of
  2143.                    modifications
  2144.            // to the record, this is field number 17
  2145.  
  2146.                    database db("Names");
  2147.  
  2148.                    int rv=rec.select(FIRST,DEL);      // Select 1st deleted
  2149.                    record
  2150.                    while(!rv)
  2151.                    {
  2152.                     rec.setdelstate(NOTDEL);
  2153.                     int nwrites=atoi(rec.getfield(17));
  2154.                     rec.setfield(17,nwrites+1);
  2155.                     rec.write();
  2156.                     rv=rec.select(NEXT,DEL);
  2157.                    }
  2158.  
  2159.  
  2160.  
  2161.  
  2162.  
  2163.  
  2164.        record::write
  2165.  
  2166.  
  2167.                int record::write(int type=OVER);
  2168.  
  2169.  
  2170.  
  2171.        Description :   Write an updated record back to the dbf file. type is
  2172.                    either OVER or NEW. If type is OVER then the record is
  2173.            written back on top of the record which was originally
  2174.                    read, this form is used for updating records. If type is
  2175.                    NEW then the record is added at the end of the dbf file.
  2176.  
  2177.                    The function returns 0 if it was successful, and NOWRUNR
  2178.                    if the application has attempted to overwrite an unread
  2179.                    record, and WRFAIL if the write failed for some other
  2180.                    reason.
  2181.  
  2182.                    The function also updates any indexes attached to the
  2183.                    current database, and it is not until this function is
  2184.                    executed that these indexes are updated.
  2185.  
  2186.                    The function checks to see if any other record classes
  2187.                    attached to the database have the same record selected,
  2188.                    if so the information is copied to these records updating
  2189.                    them.
  2190.  
  2191.  
  2192.        E.G.        See record::setfield()
  2193.  
  2194.  
  2195.  
  2196.  
  2197.  
  2198.  
  2199.        Appendix 1 - Format of database files
  2200.  
  2201.  
  2202.                                 DBase_3,_File_Format
  2203.  
  2204.  
  2205.        DBF File
  2206.  
  2207.        The DBF file holds all the records in the database together with
  2208.        global information on fields and records. It consists of 3 parts :
  2209.  
  2210.            1)  The file header which is 32 bytes long.
  2211.  
  2212.            2)  The field definitions each of which is 32 bytes long, the
  2213.                last field is followed by the byte 0DH.
  2214.  
  2215.            3)  The records each of which follows the last.
  2216.  
  2217.        File Header
  2218.  
  2219.        This is 32 bytes long, the contents are as follows :
  2220.  
  2221.        Byte 0      Bits 0-2 Version of dBase, Bit 7 flags Memo file for
  2222.            this database if set
  2223.        Bytes 1-3   Year, Month and Day (in hex) of last modification to
  2224.            database.
  2225.            Bytes 4-7   Number of records.
  2226.            Bytes 7-8   The offset of the first record from the start of the
  2227.            file.
  2228.            Bytes 10-11 The record length including the start byte.
  2229.  
  2230.        Field Definitions
  2231.  
  2232.        Each definition is 32 bytes long, the contents of each field are
  2233.        defined as follows:
  2234.  
  2235.            Bytes 0-10  Zero terminated, upper case field name, max 10
  2236.            characters.
  2237.            Byte   11   Type of the field, C, N, L, D, or M.
  2238.            Byte   16   The length of the field in characters as seen on
  2239.            screen.
  2240.            Byte   17   The number of digits right of decimal point for
  2241.            numeric fields, 0 for all others.
  2242.  
  2243.        Records
  2244.  
  2245.        Each record is stored in order of the field contents. The first byte
  2246.        of each record is either a space ' ' for an undeleted record, or a
  2247.        '*' for a deleted record. Formats for all data stored in the record
  2248.        is ASCII except for date and memo fields :
  2249.  
  2250.        Date        These fields are stored in 8 digit ascii, year then
  2251.                month then day to enable simple sorting. eg 27th
  2252.                September 1991 is stored as '19910927'.
  2253.  
  2254.  
  2255.  
  2256.  
  2257.  
  2258.            Memo        These fields are stored as 10 ascii digits which show
  2259.                        the cluster number of the memo in the dbt file. Thus
  2260.                        a value of '0000000023' is at location 23*512 in the
  2261.                        memo file. This field is all 0's for no memo on this
  2262.                        record.
  2263.  
  2264.  
  2265.  
  2266.  
  2267.  
  2268.        NDX, Index Files
  2269.  
  2270.        These files store the indexes for the database. They consist of a
  2271.        header cluster, and a complex hierarchical index structure which is
  2272.        based on 512 byte clusters.
  2273.  
  2274.        Header
  2275.  
  2276.        The header consists of the first cluster of the index file (512
  2277.        bytes). It contains information about the index file.
  2278.  
  2279.        Bytes 0-3   Cluster number of the first cluster of the index file
  2280.                        which is at the top of the tree.
  2281.  
  2282.            Bytes 4-7   Number of clusters in the file.
  2283.  
  2284.            Byte 9      Type of result, D,C or N, Logical index expressions
  2285.                        are invalid.
  2286.  
  2287.            Bytes 12-13 The size of the result of the dBase index expression
  2288.                        used for this file, in bytes.
  2289.  
  2290.            Bytes 14-15 The maximum number of index records per cluster.
  2291.  
  2292.            Bytes 16-17 The result type, 0=character, 1=numeric.
  2293.  
  2294.            Bytes 18-19 The total length of the index expression plus its
  2295.                        pointers. ie the value in bytes 12-13 + 8+n, where n
  2296.                        is chosen to round up to the nearest 4 bytes.
  2297.  
  2298.            Byte 24+    The dBase index expression used on this file, which
  2299.                is zero terminated.
  2300.  
  2301.        Index Cluster Format
  2302.  
  2303.        Each cluster consists of a number of records. Each record starts with
  2304.        two 4 byte numbers, the block number and the record number. Following
  2305.        this is the record itself which is the result of the dBase index
  2306.        expression. The cluster starts with the number of records in it, or
  2307.        the number of records-1 for block clusters, this is also a 4 byte
  2308.        number.
  2309.  
  2310.        There are two types of cluster :
  2311.  
  2312.        A record cluster contains index records where the block number is set
  2313.        to 0, and the record number is set to the record number in the dbf
  2314.        file for this index. Following the last record is a 00000000 byte
  2315.        sequence.
  2316.  
  2317.        The second type is a block cluster which pointes in a tree like
  2318.        fashion to another block cluster, or to a record cluster. This type
  2319.        has as its records the value of the index record of the last item in
  2320.        the block to which it points. A block cluster has the record number
  2321.        set to 0, and the block number set to the cluster number of the block
  2322.        to which it refers.
  2323.  
  2324.  
  2325.  
  2326.  
  2327.  
  2328.        Memo Files
  2329.  
  2330.        Memo files are organised into 512 byte clusters. Each memo takes up
  2331.        an integral number of clusters, and the text ends in the double byte
  2332.        1A, 1A. The first 4 bytes of the file hold the number of the next
  2333.        free block, and the rest of block 0 is free for user supplied
  2334.        comments. Block 1 is the first block available for use as a memo.
  2335.  
  2336.